//go:build linux

package gohttp

import (
	"bytes"
	"net/http"
	"strconv"
	"time"

	"golang.org/x/sys/unix"
)

// appendTime is a non-allocating version of []byte(t.UTC().Format(TimeFormat))
func appendTime(b []byte, t time.Time) []byte {
	const days = "SunMonTueWedThuFriSat"
	const months = "JanFebMarAprMayJunJulAugSepOctNovDec"

	t = t.UTC()
	yy, mm, dd := t.Date()
	hh, mn, ss := t.Clock()
	day := days[3*t.Weekday():]
	mon := months[3*(mm-1):]

	return append(b,
		day[0], day[1], day[2], ',', ' ',
		byte('0'+dd/10), byte('0'+dd%10), ' ',
		mon[0], mon[1], mon[2], ' ',
		byte('0'+yy/1000), byte('0'+(yy/100)%10), byte('0'+(yy/10)%10), byte('0'+yy%10), ' ',
		byte('0'+hh/10), byte('0'+hh%10), ':',
		byte('0'+mn/10), byte('0'+mn%10), ':',
		byte('0'+ss/10), byte('0'+ss%10), ' ',
		'G', 'M', 'T')
}

func NewResponse(fd int32) *response {
	return &response{
		header: make(http.Header),
		fd:     fd,
		status: 0,
	}
}

// A ResponseWriter interface is used by an HTTP handler to
// construct an HTTP response.
//
// A ResponseWriter may not be used after the Handler.ServeHTTP method
// has returned.
type response struct {
	header http.Header
	fd     int32
	status int
}

func (c *response) Header() http.Header {
	return c.header
}

func (c *response) Write(data []byte) (int, error) {
	var buffer bytes.Buffer
	if c.status == 0 || c.status == 200 {
		buffer.WriteString("HTTP/1.1 200 OK\r\n")

		for k, v := range c.header {
			buffer.WriteString(k + ": ")
			for k1, v1 := range v {
				buffer.WriteString(v1)
				if k1 > 0 {
					buffer.WriteString("; ")
				}
			}
			buffer.WriteString("\r\n")
		}

		buffer.Write(appendTime([]byte("Date: "), time.Now()))
		buffer.WriteString("\r\nContent-Length: " + strconv.Itoa(len(data)) + "\r\n")
		buffer.WriteString("Content-Type: text/plain; charset=utf-8\r\n\r\n")
		buffer.Write(data)
	}

	//fmt.Println("response:", buffer.String())
	return unix.Write(int(c.fd), buffer.Bytes())
}

func (c *response) WriteHeader(statusCode int) {
	c.status = statusCode
}
